package com.miyake.client.datamanage.plugin;

import java.util.List;

import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.google.gwt.user.client.ui.Widget;
import com.miyake.client.DataService;
import com.miyake.client.DataServiceAsync;
import com.miyake.client.DoctorsUserService;
import com.miyake.client.datamanage.AnalysisParameter;
import com.miyake.client.datamanage.AnalysisSetup;
import com.miyake.client.tools.OkCancelDialog;
import com.miyake.client.tools.ShowDialog;
import com.miyake.client.tools.SmallButton;

public abstract class MyAnalysisPluginChooser extends OkCancelDialog {

	private DataServiceAsync service = DataService.Util.getInstance();

	private String pluginKey;
	private ListBox combo;
	private VerticalPanel custom;
	private VerticalPanel paramPanel;
	private int selectedColumn;
	private AnalysisSetup setup;
	
	abstract protected Integer getColumnCount();
	
	@Override
	protected Widget getContent() {
		setHTML("Data Processing");
		VerticalPanel panel = new VerticalPanel();
		panel.setWidth("100%");
		HorizontalPanel hpanel = new HorizontalPanel();
		hpanel.setWidth("100%");
		final ListBox listBox = new ListBox();
		hpanel.add(new Label("Target Column"));
		hpanel.add(listBox);
		
		for (Integer i = 1; i <= getColumnCount(); i++) {
			listBox.addItem("C" + i.toString());
		}
		listBox.addChangeHandler(new ChangeHandler() {
			@Override
			public void onChange(ChangeEvent event) {
				selectedColumn = listBox.getSelectedIndex();
			}
		});
		selectedColumn = listBox.getSelectedIndex();
		panel.add(hpanel);

		custom = new VerticalPanel();
		paramPanel = new VerticalPanel();
		panel.add(custom);
		
		final Label plugin = new Label();
		plugin.setWidth("300px");

		custom.add(plugin);
				
		hpanel.add(new SmallButton("Plugin Market", new ClickHandler() {
			@Override
			public void onClick(ClickEvent event) {
				final PluginDialog dlg = new AnalysisPluginDialog();
				new ShowDialog() {

					@Override
					protected void onOK(String text) {
						addPlugin(dlg.getSelectedKey());
					}

					@Override
					protected DialogBox getDialogBox() {
						return dlg;
					}
					
				};
			}			
		}));
		panel.add(paramPanel);
		updatePluginList();
		return panel;
	}

	protected void updatePluginList() {
		if (combo == null) {
			HorizontalPanel h = new HorizontalPanel();
			combo = new ListBox();
			h.add(combo);
			h.add(new SmallButton("Remove", new ClickHandler() {
				@Override
				public void onClick(ClickEvent event) {
					deletePlugin(combo.getValue(combo.getSelectedIndex()));
				}
			}));
			custom.add(h);
		}
		else {
			combo.clear();
		}
		DoctorsUserService.Util.getInstance().getAnalysisPluginList(new AsyncCallback<List<PluginProperty>>() {

			@Override
			public void onFailure(Throwable caught) {
				Window.alert(caught.getMessage());
			}

			@Override
			public void onSuccess(List<PluginProperty> result) {
				for (final PluginProperty p : result) {
					combo.addItem(p.getName(), p.getKey());
				}
				combo.addChangeHandler(new ChangeHandler() {
					@Override
					public void onChange(ChangeEvent event) {
						getAnalysisParameter(combo.getValue(combo.getSelectedIndex()));
					}
				});
				getAnalysisParameter(combo.getValue(combo.getSelectedIndex()));
			}
			
		});
	}

	protected void deletePlugin(String key) {
		DoctorsUserService.Util.getInstance().removeAnalysisPlugin(key, new AsyncCallback<Void>() {
			@Override
			public void onFailure(Throwable caught) {
			}

			@Override
			public void onSuccess(Void result) {
				updatePluginList();
			}
		});
	}

	protected void getAnalysisParameter(String key) {
		this.pluginKey = key;
		DataService.Util.getInstance().getAnalysisParameters(key, new AsyncCallback<AnalysisSetup>() {

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub
				
			}

			@Override
			public void onSuccess(AnalysisSetup result) {
				setup = result;
				paramPanel.clear();
				new AnalysisParameterPanel(result, paramPanel);
			}
			
		});

		
	}

	abstract protected String getKey();
	
	public AnalysisSetup getSetup() {
		return setup;
	}

	public String getPluginKey() {
		return pluginKey;
	}
	
	private void addPlugin(String selectedKey) {
		DoctorsUserService.Util.getInstance().addAnalysisPlugin(selectedKey, new AsyncCallback<Void>() {
			@Override
			public void onFailure(Throwable caught) {
			}

			@Override
			public void onSuccess(Void result) {
				updatePluginList();
			}	
		});
	}

	public void setSelectedColumn(int selectedColumn) {
		this.selectedColumn = selectedColumn;
	}

	public int getSelectedColumn() {
		return selectedColumn;
	}
	

} 
class AnalysisParameterPanel {
	public AnalysisParameterPanel(final AnalysisSetup setup, final VerticalPanel paramPanel) {
		paramPanel.add(new Label(setup.getName()));
		for (final AnalysisParameter p : setup.getParameters()) {
			HorizontalPanel panel = new HorizontalPanel();
			panel.add(new Label(p.getTitle()));
			if (p.getType().equals("Numeric") || p.getType().equals("String")) {
				final TextBox box = new TextBox();
				box.setName(p.getId());
				box.setText(p.getValue());
				panel.add(box);
				box.addChangeHandler(new ChangeHandler() {
					@Override
					public void onChange(ChangeEvent event) {
						updateParameter(box.getName(), box.getText(), setup);
					}

				});
			}
			else if (p.getType().equals("Selection")) {
				final ListBox combo = new ListBox();
				
				for (String s : p.getSelection()) {
					combo.addItem(s);
				}
				panel.add(combo);
				combo.addChangeHandler(new ChangeHandler() {
					@Override
					public void onChange(ChangeEvent event) {
						updateParameter(p.getId(), combo.getItemText(combo.getSelectedIndex()), setup);
					}
				});
				updateParameter(p.getId(), combo.getItemText(combo.getSelectedIndex()), setup);						
			}
			panel.add(new Label(p.getUnit()));
			paramPanel.add(panel);
		}
	}
	
	private void updateParameter(String id, String text, AnalysisSetup setup) {
		for (AnalysisParameter p : setup.getParameters()) {
			if (p.getId().equals(id)) {
				p.setValue(text);
			}
		}
	}
}